package com.winit.project.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.base.beans.LoginUser;
import com.winit.common.base.web.BaseController;
import com.winit.common.filter.UserInfoUtil;
import com.winit.common.util.*;
import com.winit.deploy.service.DeployService;
import com.winit.project.core.bean.EditionInfo;
import com.winit.project.core.bean.PackageTypeEnum;
import com.winit.project.core.bean.ProjectInfo;
import com.winit.project.core.branch.Project;
import com.winit.project.core.edition.PackageEditionConfig;
import com.winit.project.manager.ProjectManager;
import com.winit.project.util.ProjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wangjian on 16/9/20.
 */
@RestController(value = "newProjectController")
@RequestMapping("/project")
public class ProjectController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(ProjectController.class);

    @Autowired
    private ProjectManager projectManager;

    @RequestMapping("/getTrunkNameList")
    @ResponseBody
    public Map<String, Object> getTrunkNameList(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("获取主干工程列表开始");

        JSONObject jsonObject = new JSONObject();
        try {
            List<ProjectInfo> list = projectManager.getProjectList(PackageTypeEnum.ALL, true, true);
            jsonObject.put("list", list);
            rtnMap.put("code", "0");
        } catch (Exception e) {
            logger.error("com.winit.project.web.ProjectController.getTrunkNameList异常.", e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "获取主干工程列表异常.e:" + e.getMessage());
        }
        return this.getRtnMap(rtnMap, new LoginUser(), jsonObject);
    }


    /**
     * 获取工程信息列表
     *
     * @param request
     * @return
     */
    @RequestMapping("/projectInfoList")
    @ResponseBody
    public Map<String, Object> projectInfoList(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("获取工程信息列表开始");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("com.winit.Project.web.NewProjectController.projectInfoList userInfo == null");
            return this.noUserRtn();
        }

        String isShowJar = request.getParameter("isShowJar");
        String onlyTrunk = request.getParameter("onlyTrunk");
        String packageType = request.getParameter("packageType");

        PackageTypeEnum typeEnum = PackageTypeEnum.ALL;
        if (!StringUtils.isEmpty(packageType)) {
            typeEnum = Enum.valueOf(PackageTypeEnum.class, packageType.toUpperCase());
        }

        JSONObject jsonObject = new JSONObject();
        try {
            List<ProjectInfo> list = projectManager.getProjectList(typeEnum
                    , Boolean.parseBoolean(onlyTrunk), Boolean.parseBoolean(isShowJar));
            jsonObject.put("list", list);
            jsonObject.put("editionCountMax", ConfigUtil.getValue("edition_count_max"));
            rtnMap.put("code", "0");
        } catch (Exception e) {
            logger.error("projectInfoList异常.", e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "获取工程信息列表异常.e:" + e.getMessage());
        }
        return this.getRtnMap(rtnMap, userInfo, jsonObject);
    }

    @RequestMapping("/projectListByTrunk")
    @ResponseBody
    public Map<String, Object> projectListByTrunk(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("com.winit.project.web.ProjectController.projectListByTrunk");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("com.winit.project.web.ProjectController.projectListByTrunk userInfo == null");
            return this.noUserRtn();
        }

        String trunkName = request.getParameter("trunkName");

        JSONObject jsonObject = new JSONObject();
        try {
            List<ProjectInfo> list = projectManager.getProjectListByTrunkName(trunkName);
            jsonObject.put("list", list);
            jsonObject.put("editionCountMax", ConfigUtil.getValue("edition_count_max"));
            rtnMap.put("code", "0");
        } catch (Exception e) {
            logger.error("com.winit.project.web.ProjectController.projectListByTrunk异常.", e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "获取工程信息列表异常.e:" + e.getMessage());
        }
        return this.getRtnMap(rtnMap, userInfo, jsonObject);
    }

    /**
     * 获取工程信息
     *
     * @param request
     * @return
     */
    @RequestMapping("/getProject")
    @ResponseBody
    public Map<String, Object> getProject(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("查看工程信息开始");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("查询工程信息,获取用户信息为空");
            return this.noUserRtn();
        }
        String projectName = request.getParameter("projectName");
        if (StringUtils.isEmpty(projectName)) {
            logger.info("查询工程信息,工程名为空");
            return this.paramEmptyRtn(userInfo, "projectName");
        }

        ProjectInfo info = null;
        try {
            Project project = new Project(projectName, true);
            info = project.projectInfo;
        } catch (Exception e) {
            logger.error("查询工程信息异常,projectName=" + projectName, e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "查询工程信息异常s." + e.getMessage());
            return this.getRtnMap(rtnMap, userInfo, new JSONObject());
        }
        rtnMap.put("code", "0");
        rtnMap.put("desc", "查询成功");
        return this.getRtnMap(rtnMap, userInfo, (JSONObject) JSONObject.toJSON(info));
    }

    /**
     * 编辑工程信息  新增/修改
     *
     * @param request
     * @return
     */
    @RequestMapping("/editProject")
    @ResponseBody
    public Map<String, Object> editProject(HttpServletRequest request) {
        LoginUser loginUser = UserInfoUtil.getUserInfo(request);
        if (loginUser == null) {
            return this.noUserRtn();
        }

        String projectInfo = request.getParameter("projectInfo");
        if (StringUtils.isEmpty(projectInfo)) {
            logger.info("编辑工程,工程信息为空");
            return this.paramEmptyRtn(loginUser, "工程信息");
        }

        logger.info("编辑工程信息,projectInfo=" + projectInfo + ",loginUser=" + ObjectToString.getString(loginUser));

        ProjectInfo info = JSONObject.toJavaObject(JSON.parseObject(projectInfo), ProjectInfo.class);

        Map<String, Object> rtnMap = new HashMap<>();
        try {
            boolean flag = projectManager.editProject(info);
            rtnMap.put("code", flag ? "0" : "1");
            rtnMap.put("desc", flag ? "保存成功" : "保存失败");
        } catch (Exception e) {
            logger.error("编辑工程信息异常。projectInfo=" + projectInfo, e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "编辑工程信息异常." + e.getMessage());
        }
        logger.info("编辑工程信息,projectInfo=" + projectInfo + ",loginUser=" + ObjectToString.getString(loginUser) + ",rtnMap=" + rtnMap);
        return getRtnMap(rtnMap, loginUser, new JSONObject());
    }

    /**
     * 为项目创建工程
     *
     * @param request
     * @return
     */
    @RequestMapping("/addProjectForPlan")
    @ResponseBody
    public Map<String, Object> addProjectForPlan(HttpServletRequest request) {
        LoginUser loginUser = UserInfoUtil.getUserInfo(request);
        if (loginUser == null) {
            return this.noUserRtn();
        }

        String trunkName = request.getParameter("trunkName");
        String projectName = request.getParameter("projectName");
        String vcsPath = request.getParameter("vcsPath");
        String dependency = request.getParameter("dependency");
        if (StringUtils.isEmpty(trunkName)) {
            logger.info("创建工程,trunkName为空");
            return this.paramEmptyRtn(loginUser, "trunkName");
        }
        if (StringUtils.isEmpty(projectName)) {
            logger.info("创建工程,projectName为空");
            return this.paramEmptyRtn(loginUser, "projectName");
        }
        if (StringUtils.isEmpty(vcsPath)) {
            logger.info("创建工程,vcsPath为空");
            return this.paramEmptyRtn(loginUser, "vcsPath");
        }
        if (StringUtils.isEmpty(dependency)) {
            logger.info("创建工程,dependency为空");
            return this.paramEmptyRtn(loginUser, "dependency");
        }

        logger.info("com.winit.project.web.ProjectController.addProjectForPlan,trunkName=" + trunkName + "，projectName＝" + projectName
                + ",vcsPath=" + vcsPath + ",dependency=" + dependency + ",loginUser=" + ObjectToString.getString(loginUser));

        Map<String, Object> rtnMap = new HashMap<>();
        JSONObject json = new JSONObject();
        try {
            boolean flag = projectManager.addProjectForPlan(trunkName, projectName, vcsPath, dependency);
            rtnMap.put("code", flag ? "0" : "1");
            rtnMap.put("desc", flag ? "创建工程成功" : "创建工程失败");
            if (flag) {
                json.put("localPath", ProjectUtil.getProjectFilePath(projectName));
                json.put("warName", trunkName);
                ProjectInfo info = projectManager.getProjectInfo(projectName);
                if("maven_war".equals(info.getPackageType())){
                    json.put("warName", projectManager.getProjectInfo(projectName).getWarName());
                }else if("php".equals(info.getPackageType()) || "ant_android".equals(info.getPackageType())){
                    json.put("warName", projectManager.getProjectInfo(projectName).getPackageName());
                }
            }
        } catch (Exception e) {
            logger.error("com.winit.project.web.ProjectController.addProjectForPlan error,trunkName=" + trunkName + "，projectName＝" + projectName + ",vcsPath=" + vcsPath);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "创建工程异常." + e.getMessage());
        }
        logger.info("com.winit.project.web.ProjectController.addProjectForPlan,projectName=" + projectName + ",loginUser=" + ObjectToString.getString(loginUser) + ",rtnMap=" + rtnMap);
        return getRtnMap(rtnMap, loginUser, json);
    }


    /**
     * 获取工程版本信息列表
     *
     * @param request
     * @return
     */
    @RequestMapping("/editionInfoList")
    @ResponseBody
    public Map<String, Object> editionInfoList(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("获取工程版本信息列表开始");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("获取工程版本信息列表,获取用户信息为空");
            return this.noUserRtn();
        }

        String projectName = request.getParameter("projectName");
        Assert.hasText(projectName, "获取工程版本信息列表,工程名为空");

        String hasDefault = request.getParameter("hasDefault");

        JSONObject jsonObject = new JSONObject();
        List<EditionInfo> list = new ArrayList<>();
        try {
            if (StringUtils.isEmpty(hasDefault)) {
                list = projectManager.getProjectEditionList(projectName, true);
            } else {
                list = projectManager.getProjectEditionList(projectName, true, Boolean.parseBoolean(hasDefault));
            }

            rtnMap.put("code", "0");
        } catch (Exception e) {
            logger.error("获取工程版本信息列表异常.", e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "获取工程版本信息列表异常.e:" + e.getMessage());
        }
        jsonObject.put("list", list);
        return this.getRtnMap(rtnMap, userInfo, jsonObject);
    }


    @RequestMapping("/createNewEdition")
    @ResponseBody
    public Map<String, Object> createNewEdition(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("生成版本开始");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("生成版本,获取用户信息为空");
            return this.noUserRtn();
        }

        String projectName = request.getParameter("projectName");
        Assert.hasText(projectName, "生成版本,工程名为空");

        JSONObject object = new JSONObject();
        try {
            String editionNum =   projectManager.createNewEdition(projectName, userInfo);
            rtnMap.put("code", "0");
            object.put("editionNum", editionNum);
        } catch (Exception e) {
            logger.error("生成版本异常.projectName=" + projectName, e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "生成版本异常.e:" + e.getMessage());
        }
        return this.getRtnMap(rtnMap, userInfo, object);
    }


    /**
     * 修改版本备注
     *
     * @param request
     * @return
     */
    @RequestMapping("/editEditionDesc")
    @ResponseBody
    public Map<String, Object> editEditionDesc(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("修改版本备注开始");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("修改版本备注,获取用户信息为空");
            return this.noUserRtn();
        }

        String projectName = request.getParameter("projectName");
        String editionNum = request.getParameter("editionNum");
        String desc = request.getParameter("desc");
        Assert.hasText(projectName, "修改版本备注,工程名为空");
        Assert.hasText(editionNum, "修改版本备注,版本号为空");

        try {
            PackageEditionConfig editionConfig = new PackageEditionConfig(projectName, editionNum, true);
            editionConfig.setDesc(desc);
            boolean flag = editionConfig.saveToFile();
            if (flag) {
                rtnMap.put("code", "0");
            } else {
                rtnMap.put("code", "1");
                rtnMap.put("desc", "修改版本备注失败");
            }
        } catch (Exception e) {
            logger.error("修改版本备注异常.projectName=" + projectName + ",editionNum=" + editionNum + ",desc=" + desc, e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "修改版本备注异常.e:" + e.getMessage());
        }

        return this.getRtnMap(rtnMap, userInfo, new JSONObject());
    }

    /**
     * 删除工程
     *
     * @param request
     * @return
     */
    @RequestMapping("/delProject")
    @ResponseBody
    public Map<String, Object> delProject(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        LoginUser loginUser = UserInfoUtil.getUserInfo(request);
        if (loginUser == null) {
            return this.noUserRtn();
        }
        String projectName = request.getParameter("projectName");
        logger.info("删除工程,projectName=" + projectName + ",loginUser=" + ObjectToString.getString(loginUser));
        if (StringUtils.isEmpty(projectName)) {
            return this.paramEmptyRtn(loginUser, "工程名");
        }
        boolean flag = false;
        try {
            flag = projectManager.delProject(projectName);
            rtnMap.put("code", flag ? "0" : "1");
            rtnMap.put("desc", flag ? "删除成功" : "删除失败");
        } catch (Exception e) {
            logger.error("删除工程异常,projectName=" + projectName, e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "删除工程异常,projectName=" + projectName + ".e:" + e.getMessage());
        }
        logger.info("删除工程,projectName=" + projectName + ",loginUser=" + ObjectToString.getString(loginUser) + ",flag=" + flag);
        return getRtnMap(rtnMap, loginUser, new JSONObject());
    }
}
